/* eslint-disable @typescript-eslint/no-unused-vars */
import { useEffect, useCallback } from 'react';
import { Graph } from '@antv/x6';
import type { Cell } from '@antv/x6';
import '@antv/x6-react-shape';
import styles from './index.less';
import { connect } from '@umijs/max';
import type { Dispatch } from '@umijs/max';
import { ReactShape } from '@antv/x6-react-shape';
// import { CustomNode, UserNodeTpl } from './components';
import type { X6API, userAPI } from '@/models/models';
import insertCss from 'insert-css';
import UserNodeTpl from '@/pages/X6Pages/X6Case01/components/UserNodeTpl';
import CustomNode from '@/pages/X6Pages/X6Case01/components/CustomNode';

interface IProps extends X6API.IState {
  dispatch: Dispatch;
  userList: userAPI.userDataItem[];
}

interface delToolIProps {
  offSet: { x: number | string; y: number | string };
  collapsed?: boolean;
}

// eslint-disable-next-line prefer-const
let delTool: ({ offSet, collapsed }: delToolIProps) => Record<string, unknown>[];

class CustomUserGroup extends ReactShape {
  private collapsed: boolean = false;
  // private expandSize: { width: number; height: number };

  isCollapsed() {
    return this.collapsed;
  }

  toggleButtonVisibility(visible: boolean) {
    this.attr('buttonGroup', {
      display: visible ? 'block' : 'none',
    });
  }

  toggleCollapse(offSet: delToolIProps['offSet'], collapsed?: delToolIProps['collapsed']) {
    const target = collapsed == null ? !this.collapsed : collapsed;

    // ! 修改 展开/折叠 按钮的样式： 方法二： 点击 切换调用toggleCollapse方法时，将 offSet 传递过来 修改tools
    this.removeTools();
    // @ts-ignore
    this.addTools(delTool({ offSet, collapsed: target }));
    this.collapsed = target;
  }
}

delTool = ({ offSet, collapsed = false }) => {
  return [
    {
      name: 'button',
      zIndex: 0,
      args: {
        x: '100%',
        y: 0,
        offset: offSet,
        markup: [
          {
            tagName: 'g',
            selector: 'buttonGroup',
            attrs: {
              refX: '100%',
              refY: '50%',
            },
            children: [
              {
                tagName: 'rect',
                selector: 'button',
                attrs: {
                  fill: '#5F95FF',
                  stroke: 'none',
                  x: -10,
                  y: -10,
                  height: 20,
                  width: 30,
                  rx: 10,
                  ry: 10,
                  cursor: 'pointer',
                  event: 'node:collapse',
                },
              },
              {
                tagName: 'path',
                selector: 'buttonSign',
                attrs: {
                  // refX: -115,
                  // refY: 115,
                  stroke: '#FFFFFF',
                  strokeWidth: 1.6,
                  d: collapsed ? 'M 4 1 12 1 M 8 -3 8 5' : 'M 4 1 12 1',
                },
              },
            ],
          },
        ],
        onClick({ cell }: { cell: CustomUserGroup }) {
          // const children = cell.getChildren();
          console.log('node:delete:button', cell, cell.isCollapsed());

          cell.toggleCollapse(offSet);
          // eslint-disable-next-line @typescript-eslint/no-shadow
          const collapsed = cell.isCollapsed();
          // ! 修改 展开/折叠 按钮的样式： 方法一： 点击 切换时，重新修改 使用 removeTools 和 addTools 修改 tools
          // cell.removeTools();
          // cell.addTools(delTool({ offSet, collapsed }));
          const collapse = (parent: CustomUserGroup) => {
            const cells = parent.getChildren();
            console.log('node:delete:button', cells);
            if (cells) {
              cells.forEach((cellItem: Cell) => {
                if (collapsed) {
                  cellItem.hide();
                } else {
                  cellItem.show();
                }
                if (cellItem instanceof CustomUserGroup) {
                  if (!cellItem.isCollapsed()) {
                    collapse(cellItem);
                  }
                }
              });
            }
          };

          collapse(cell);
        },
      },
    },
  ];
};

// @ts-ignore
insertCss(`
  @keyframes ant-line {
    to {
        stroke-dashoffset: -1000
    }
  }
  .x6-node-selected .mobileDetailContainerSelected {
    border-color: #52c41a;
    box-shadow: 0 0 0 4px #ccecc0;
  }
`);

Graph.registerNode(
  'user-parent-node',
  {
    inherit: CustomUserGroup,
    width: 180,
    height: 36,
    x: 0,
    y: 50,
    zIndex: 10,
    component: <div className={styles.divBox}>自定义用户列表父节点</div>,
    tools: delTool({ offSet: { x: 0, y: 20 } }),
  },
  true,
);
function X6Case01(props: IProps) {
  const { mobileDataList, userList, dispatch } = props;

  let graph: any;

  useEffect(() => {
    const container = document.getElementById('container');
    if (container) {
      graph = new Graph({
        container,
        width: window.innerWidth - 100,
        height: window.innerHeight,
        async: true,
        // frozen: true,
        panning: {
          // 按住 shift 画布拖拽
          enabled: true,
          modifiers: 'shift',
        },
        background: {
          color: '#fff', // 设置画布背景颜色
        },
        grid: {
          size: 10, // 网格大小 10px
          visible: true, // 渲染网格背景
        },
        selecting: {
          enabled: true,
          multiple: true,
          rubberEdge: true,
          rubberNode: true,
          modifiers: 'shift',
          rubberband: true,
        },
      });
    }
  }, []);

  const createGroup = useCallback(
    (id: string, x: number, y: number, width: number, height: number, extra: any) => {
      const group = new CustomUserGroup({
        id,
        x,
        y,
        width,
        height,
        ...extra,
      });
      return graph.addNode(group);
    },
    [graph],
  );

  // 创建连线
  const createEdge = useCallback(
    (
      id: string,
      source: string | object,
      target: string | object,
      vertices?: { x: number; y: number }[],
    ) => {
      return graph.addEdge({
        id,
        source,
        target,
        vertices,
        label: id,
        zIndex: 0,
        connector: { name: 'smooth' },
        attrs: {
          line: {
            stroke: '#1890ff',
            strokeDasharray: 5,
            targetMarker: 'classic',
            style: {
              animation: 'ant-line 30s infinite linear',
            },
          },
        },
      });
    },
    [graph],
  );

  const renderNode = (
    nodeData: X6API.mobileDataItem | X6API.mobileDataItem[] | undefined,
    startX: number,
    startY: number,
    parentNode: any,
    curNodeWidth: number,
  ) => {
    const colGetter = 100;
    if (!nodeData) return;
    const renderCurNode = (
      curNode: X6API.mobileDataItem,
      xAxis: number,
      yAxis: number,
      isShowTool: boolean,
      curNodeHeight: number,
    ) => {
      console.log('********', curNode);
      const childNode = createGroup(curNode.title, xAxis, yAxis, curNodeWidth, 20, {
        component: () => (
          <CustomNode
            mobileDataItem={curNode}
            // case06DataList={case06DataList}
            dispatch={dispatch}
          />
        ),
        tools: isShowTool && delTool({ offSet: { x: 0, y: 10 } }),
        data: curNode,
      });
      parentNode.addChild(childNode);
      createEdge(
        '',
        {
          cell: parentNode,
          anchor: {
            name: 'right',
            args: {
              dx: 0,
              // dy: (parentHeight1 || 0) / 2,
            },
          },
        },
        {
          cell: childNode,
          anchor: {
            name: 'left',
            args: {
              dx: 0,
              dy: curNodeHeight / 2,
            },
          },
        },
      );
      return childNode;
    };
    if (Object.prototype.toString.call(nodeData) === '[object Array]') {
    } else if (Object.prototype.toString.call(nodeData) === '[object Object]') {
      const nodeDataObj = nodeData as X6API.mobileDataItem;
      const children = nodeDataObj.children;
      const childNode = renderCurNode(
        nodeDataObj,
        startX,
        startY,
        !!children?.length,
        nodeDataObj.height || 100,
      );
      if (Object.prototype.toString.call(children) === '[object Array]') {
        renderNode(children, startX + curNodeWidth + colGetter, startY, childNode, curNodeWidth);
      }
    }
  };

  useEffect(() => {
    if (!graph) return;
    const detailOptions = {
      title: '用户列表',
      userList,
    };

    const userParent = graph.addNode({
      shape: 'user-parent-node',
    });

    Graph.registerNode(
      'user-node',
      {
        inherit: CustomUserGroup,
        x: 300,
        y: 50,
        width: 300,
        height: 40,
        component: <UserNodeTpl {...detailOptions} />,
        tools: delTool({ offSet: { x: 0, y: 20 } }),
      },
      true,
    );

    const userNode = graph.addNode({
      shape: 'user-node',
    });

    console.log('node***********重新渲染');
    renderNode(mobileDataList, 680, 100, userNode, 360);
    // graph.unfreeze();
    // 创建连线
    createEdge(
      '',
      {
        cell: userParent,
        anchor: {
          name: 'right',
          args: {
            dx: 20,
            // rotate: true,
          },
        },
      },
      userNode,
    );

    graph.on('node:delete', ({ view, e }: { view: any; e: any }) => {
      console.log('node:delete', view, e);
      e.stopPropagation();
      view.cell.remove();
    });
    //
    // graph.on('node:click', ({ node }) => {
    //   const data = node.getData();
    //   node.setData({
    //     ...data,
    //     调用方式: data['调用方式'] === '同步' ? '数据改变' : '同步111',
    //     height: data.height === 200 ? 40 : 200,
    //   });
    //
    //   mobileDataList.children.forEach((item) => {
    //     if (item.title === data.title) {
    //       item.height = item.height === 200 ? 40 : 200;
    //       // item.调用方式 = item.调用方式 === '同步' ? '数据改变' : '同步111';
    //     }
    //   });
    //   dispatch({
    //     type: 'X6Model/save',
    //     payload: {
    //       mobileDataList,
    //     },
    //   });
    //   console.log('node click', node, mobileDataList, data);
    //   // updateData(mobileDataList)
    //   // graph.resetCells();
    //   // renderNodeFactory(mobileDataList, 600, 0)(mobileDataList, 0, 0, userNode, 360);
    // });
    //
    // graph.on('node:change:data', (props: any) => {
    //   const { node } = props;
    //   console.log(
    //     'node:change:data',
    //     node,
    //   );
    //   // graph.resetCells(graph.getCells());
    //   // graph.removeCells(node.getParent().children);
    //   // renderNodeFactory(mobileDataList, 600, 0)(mobileDataList, 0, 0, userNode, 360);
    // });

    // 将内容放置到画布中间
    // graph.centerContent();

    return () => {
      graph.dispose();
    };
  }, []);

  return (
    <>
      <div id="container" />
    </>
  );
}

export default connect(
  ({ x6Model, userModel }: { x6Model: X6API.IState; userModel: userAPI.IState }) => {
    return {
      mobileDataList: x6Model.mobileDataList,
      userList: userModel.userList,
    };
  },
)(X6Case01);
